package org.session.repository.redis;

import java.util.Properties;
import java.util.concurrent.TimeoutException;

import org.session.service.IConnectionManager;
import org.session.util.PropertyLoader;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Protocol;

final class RedisConnectionManager implements IConnectionManager {
    private static final RedisConnectionManager INSTANCE = new RedisConnectionManager();
    private static final Properties properties = PropertyLoader
            .getAllProperties("redis.properties");
    private static final JedisPool jedisPool;

    static {
        jedisPool = new JedisPool(properties.getProperty("host"),
                Protocol.DEFAULT_PORT, Integer.parseInt(properties
                        .getProperty("pooltimeout")));
        jedisPool.setResourcesNumber(Integer.parseInt(properties
                .getProperty("poolsize")));
        jedisPool.init();
        try {
            // Give it a little breather
            Thread.sleep(50L);
        } catch (InterruptedException interruptedException) {
            throw new RuntimeException(interruptedException);
        }
    }

    private RedisConnectionManager() {
    }

    static RedisConnectionManager getInstance() {
        return INSTANCE;
    }

    @Override
    public Object getConnection() {
        if (jedisPool == null) {
            throw new UnsupportedOperationException(
                    "Cannot get a jedis connection from a null jedispool");
        }
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource(Integer.parseInt(properties
                    .getProperty("conexntimeout")));
        } catch (TimeoutException timeoutException) {
            throw new RuntimeException(timeoutException);
        }

        return jedis;
    }

    @Override
    public boolean closeConnection(Object connection) {
        if (jedisPool == null) {
            throw new UnsupportedOperationException(
                    "Cannot return a jedis connection to a null jedispool");
        }
        if (connection == null) {
            throw new UnsupportedOperationException(
                    "Cannot return a null jedis connection to jedispool");
        }

        jedisPool.returnResource((Jedis) connection);

        return true;
    }

    @Override
    public boolean shutdown() {
        boolean success = false;
        if (jedisPool != null) {
            jedisPool.destroy();
            success = true;
        } else {
            throw new UnsupportedOperationException(
                    "Cannot shutdown repository. Null jedispool indicates it is already shutdown");
        }

        return success;
    }

}
